﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Web;
using System.Diagnostics;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Test")]
namespace APILocawebGatewayUI.Nucleo
{

    public class Utilidades
    {


        #region requisicoes
        /// <summary>
        /// Retorna valor da variável na querystring
        /// </summary>
        /// <param name="queryString"></param>
        /// <param name="chave"></param>
        /// <returns></returns>
        public static string PesquisarQueryString(string queryString, string chave)
        {
            string resposta = null;
            if (queryString.Length > 0 && queryString.Contains(chave))
            {
                if (queryString.Contains("?"))
                    queryString = queryString.Substring(1, queryString.Length - 1);

                for (int i = 0; i < queryString.Split('&').Length; i++)
                {
                    string subQuery = queryString.Split('&')[i];
                    string subQueryKey = subQuery.Split('=')[0];
                    string subQueryValue = subQuery.Split('=')[1];
                    if (subQueryKey.ToLower() == chave.ToLower())
                        return subQueryValue;
                }
            }
            return resposta;
        }


        /// <summary>
        /// Este método gera uma query string usando um NameValueCollection como base
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public static string GerarQueryString(NameValueCollection query)
        {
            StringBuilder queryString = new StringBuilder();
            foreach (var item in query.AllKeys)
            {
                queryString.Append(item);
                queryString.Append("=");
                queryString.Append(query[item]);
                queryString.Append("&");
            }
            queryString.Remove(queryString.Length - 1, 1);

            return queryString.ToString();
        }

        /// <summary>
        /// Este método Realiza uma requisição modo POST
        /// </summary>
        /// <param name="query">Dados que serão utilizados para formar a queryString, Dados devem estar no padrão NameValueCollection</param>
        /// <returns></returns>
        public static string RequisicaoPOST(NameValueCollection query)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(GerarQueryString(query));

            HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(APILocawebConfiguration.Instancia.Url);

            webReq.Method = WebRequestMethods.Http.Post;
            webReq.ContentType = "application/x-www-form-urlencoded";
            webReq.ContentLength = buffer.Length;
            webReq.Timeout = 120000;

            Stream postData = webReq.GetRequestStream();
            postData.Write(buffer, 0, buffer.Length);
            postData.Close();

            HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();

            Stream resposta = webResp.GetResponseStream();
            StreamReader _resposta = new StreamReader(resposta);
            webReq = null;
            postData = null;
            webResp = null;
            return _resposta.ReadToEnd();
        }

        /// <summary>
        /// Este método realiza uma requisição modo GET
        /// </summary>
        /// <param name="url">URL para a qual a requisição será realizada</param>
        /// <param name="query"> queryString da requisição</param>
        /// <returns></returns>
        public static String RequisicaoGET(String url, NameValueCollection query)
        {
            HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(url + "?" + GerarQueryString(query));

            webReq.Method = WebRequestMethods.Http.Get;
            webReq.Timeout = 2 * 60 * 1000;

            var respostaRequisicao = webReq.GetResponse();
            StreamReader streamIn = new StreamReader(respostaRequisicao.GetResponseStream());
            String resposta = streamIn.ReadToEnd();
            respostaRequisicao.Close();
            streamIn.Close();
            return resposta;
        }

        #endregion

        #region ExtrairString

        public static string ExtrairString(string fonte, string delimitadorInicial, string delimitadorFinal)
        {
            return ExtrairString(fonte, delimitadorInicial, delimitadorFinal, false, false);
        }

        private static string ExtrairString(string fonte, string delimitadorInicial, string delimitadorFinal, bool CaseSensitive, bool permititDelimitadorFinalAusente)
        {
            int At1, At2;

            if (string.IsNullOrEmpty(fonte))
                return "";

            if (CaseSensitive)
            {
                At1 = fonte.IndexOf(delimitadorInicial);
                if (At1 == -1)
                    return "";

                At2 = fonte.IndexOf(delimitadorFinal, At1 + delimitadorInicial.Length);
            }
            else
            {
                string Lower = fonte.ToLower();
                At1 = Lower.IndexOf(delimitadorInicial.ToLower());
                if (At1 == -1)
                    return "";

                At2 = Lower.IndexOf(delimitadorFinal.ToLower(), At1 + delimitadorInicial.Length);
            }

            if (permititDelimitadorFinalAusente && At2 == -1)
                return fonte.Substring(At1 + delimitadorInicial.Length);

            if (At1 > -1 && At2 > 1)
                return fonte.Substring(At1 + delimitadorInicial.Length, At2 - At1 - delimitadorInicial.Length);

            return "";
        }

        #endregion

        #region Debugar

        /// <summary>
        /// Este método é utilizado para debugar a aplicação
        /// </summary>
        /// <param name="formaPagamento"></param>
        /// <param name="mensagem"></param>
        /// <param name="objetoCorrente"></param>
        internal static void Debugar(String formaPagamento, String mensagem, object objetoCorrente)
        {
            if (!APILocawebConfiguration.Instancia.Debug)
                return;

            Dictionary<String, String> valores = new Dictionary<string, string>();
            valores.Add("Data e Hora", DateTime.Now.ToString());
            StackTrace stackTrace = new StackTrace();
            valores.Add("Método:", stackTrace.GetFrame(1).GetMethod().Name);
            valores.Add("Mensagem", mensagem);
            foreach (var item in ObterPropriedadesEValoresDeObjeto(objetoCorrente))
                valores.Add(item.Key, item.Value);

            EnviarMensagemDebug(formaPagamento, valores);
        }

        internal static void Debug(string message)
        {
            Debug("higor.crr@gmail.com", "Debug", message);
        }

        internal static void Debug(string to, string subject, string message)
        {
            try
            {

                MailMessage msg = new MailMessage
                {
                    From = new MailAddress("higor.crr0@gmail.com")
                };

                msg.To.Add(new MailAddress(to));
                msg.Subject = subject;
                msg.Body = message;
                msg.IsBodyHtml = true;
                SmtpClient client = new SmtpClient("smtp.gmail.com")
                {
                    EnableSsl = true,
                    UseDefaultCredentials = true,
                    Credentials = new NetworkCredential("higor.crr0@gmail.com", "hrty_jdjd")
                };
                client.Send(msg);
            }
            catch (Exception)
            {

            }
        }

        internal static Dictionary<String, String> ObterPropriedadesEValoresDeObjeto(object objeto)
        {
            Dictionary<String, String> propriedadesValores = new Dictionary<string, string>();
            foreach (var propriedade in objeto.GetType().GetProperties())
                propriedadesValores.Add(propriedade.Name, propriedade.GetValue(objeto, null).ToString());
            return propriedadesValores;
        }

        internal static void EnviarMensagemDebug(String formaPagamento, Dictionary<String, String> valores)
        {
            if (!APILocawebConfiguration.Instancia.Debug)
                return;
            try
            {
                StringBuilder mensagem = new StringBuilder();
                mensagem.AppendLine("Debug APILocawebGateway<br>");
                mensagem.AppendLine("Forma de Pagamento:" + formaPagamento);
                foreach (var item in valores.Keys)
                    mensagem.AppendLine(item + ":" + valores[item] + "<br>");
                CorreioEmail.EnviarEmail("Locaweb Gateway-Debug", mensagem.ToString());
            }
            catch (Exception)
            {
            }
        }

        #endregion

        #region Email
        public class CorreioEmail
        {
            public CorreioEmail()
            {
                //
                // TODO: Add constructor logic here
                //
            }
            public static bool EnviarEmail(string subject, string message)
            {
                try
                {
                    NetworkCredential loginInfo = new NetworkCredential(APILocawebConfiguration.Instancia.Email, APILocawebConfiguration.Instancia.Senha);
                    MailMessage msg = new MailMessage();
                    msg.From = new MailAddress(APILocawebConfiguration.Instancia.Email);
                    msg.To.Add(new MailAddress(APILocawebConfiguration.Instancia.Email));
                    msg.Subject = subject;
                    msg.Body = message;
                    msg.IsBodyHtml = false;
                    SmtpClient client = new SmtpClient(APILocawebConfiguration.Instancia.Smtp);
                    client.EnableSsl = true;
                    client.UseDefaultCredentials = true;
                    client.Credentials = loginInfo;
                    client.Send(msg);

                    return true;
                }
                catch (Exception)
                {
                    return false;
                }

            }
        }

        #endregion


        #region Formatação de valores
        public static String FormatarValorMoedaParaFormulario(Decimal price)
        {
            return price.ToString("0.00").Replace(".", "").Replace(",", "");
        }
        #endregion

    }
}